# -*- coding: utf-8 -*-

"""
Module implementing DPy2Exe.
"""

from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QDialog, QMessageBox, QFileDialog

from Ui_wmain import Ui_Dialog

import pickle, sys
from cx_Freeze import main
from os import path


class DPy2Exe(QDialog, Ui_Dialog):
    """
    python文件生成exe
    """
    def __init__(self, parent=None):
        """
        默认初始化
        """
        super(DPy2Exe, self).__init__(parent)
        self.setupUi(self)
        self.setKeys = ['target-name', 'target-dir', 'base-name', 'icon']
        self.setting = dict(zip(self.setKeys, ('', 'dist', '', '')))
        self.setting['script'] = ''
        self.setting['useDefDir'] = True
        self.setting['useWin'] = True
        self.updateSetting()
        
    def getExeName(self, filename):
        '获得文件的默认exe名称'
        return '.'.join(path.basename(filename).split('.')[:-1])
    
    @pyqtSlot()
    def on_btnScript_clicked(self):
        """
        脚本浏览
        """
        filename, filter = QFileDialog.getOpenFileName(self, "从文件获取参数", self.leScript.text(), "参数文件 (*.py *.pyw)")
        if not filename: return
        self.leScript.setText(filename)
        #生成默认可执行文件名
        self.leTargetName.setText(self.getExeName(filename))
    
    @pyqtSlot(bool)
    def on_cbUseDefDir_clicked(self, checked):
        """
        是否使用默认目录
        """
        self.setting['useDefDir'] = checked
        if checked:
            self.leTargetDir.setEnabled(False)
            self.btnTargetDir.setEnabled(False)
        else:
            self.leTargetDir.setEnabled(True)
            self.btnTargetDir.setEnabled(True)
        
    @pyqtSlot(bool)
    def on_cbUseWin_clicked(self, checked):
        '是否使用窗口'
        self.setting['useWin'] = checked
    
    @pyqtSlot()
    def on_btnTargetDir_clicked(self):
        """
        目标目录浏览
        """
        dirName = QFileDialog.getExistingDirectory(self, "选择目标目录", path.dirname(self.leScript.text()),
            QFileDialog.Options(QFileDialog.ShowDirsOnly))
        if not dirName: return
        self.leTargetDir.setText(dirName)
    
    @pyqtSlot()
    def on_btnIcon_clicked(self):
        """
        图标浏览
        """
        filename, filter = QFileDialog.getOpenFileName(self, "图标选取", self.leScript.text(), "图标文件 (*.ico)")
        if not filename: return
        self.leIcon.setText(filename)
    
    @pyqtSlot()
    def on_btnOpen_clicked(self):
        """
        打开
        """
        filename, filter = QFileDialog.getOpenFileName(self, "文件生成数据", "", "数据文件 (*.p2e)")
        if not filename: return
        setdict = pickle.load(open(filename, 'rb'))
        for key in setdict:
            self.setting[key] = setdict[key]
        self.updateSetting()
    
    @pyqtSlot()
    def on_btnSave_clicked(self):
        """
        保存
        """
        filename, filter = QFileDialog.getSaveFileName(self, "文件生成数据", "newprj", "数据文件 (*.p2e)")
        if not filename: return
        self.getSetting()
        pickle.dump(self.setting, open(filename, 'wb'))
    
    @pyqtSlot()
    def on_btnGenerate_clicked(self):
        """
        生成
        """
        # 设定设置值
        self.getSetting()
        #如果没有主脚本则提示并返回
        if not path.exists(self.setting['script']):
            QMessageBox.warning(self, '主代码错误', '缺少主代码,或者主代码不存在!')
            return            
        argv = [self.setting['script']]
        for key in self.setKeys:
            if self.setting[key]:
                argv.append('--' + key)
                argv.append(self.setting[key])
        sys.argv[1:] = argv
        curstdout = sys.stdout
        curstderr = sys.stderr
        logfile = open('genmsg.log', 'w')
        sys.stderr = sys.stdout = logfile
        print(argv)
        try:
            main()
        except:
            QMessageBox.warning(self, '生成错误', str(sys.exc_info()[1]))
        else:
            QMessageBox.information(self, '生成成功', '成功生成exe文件!')
        sys.stdout = curstdout
        sys.stderr = curstderr
        logfile.close()
        
    def getSetting(self):
        '从界面中获取设定值'
        self.setting['script'] = self.leScript.text()
        #如果选用默认目录则用脚本目录下的dist目录
        if self.setting['useDefDir']:
            self.setting['target-dir'] = path.dirname(self.setting['script']) + '/dist'
        else:
            self.setting['target-dir'] = self.leTargetDir.text()
        self.setting['base-name'] = 'Win32GUI' if self.setting['useWin'] else ''
        #判断当前的应用程序名称是否为默认值
        if self.leTargetName.text() and self.leTargetName.text() != self.getExeName(self.setting['script']):
            self.setting['target-name'] = self.leTargetName.text() + '.exe'
        else:
            self.setting['target-name'] = ''
        self.setting['icon'] = self.leIcon.text()
        
    def updateSetting(self):
        '将设定值更新到界面中'
        self.leScript.setText(self.setting['script'])
        self.leTargetDir.setText(self.setting['target-dir'])
        self.leTargetName.setText(self.getExeName(self.setting['target-name']))
        self.leIcon.setText(self.setting['icon'])
        self.cbUseDefDir.setChecked(self.setting['useDefDir'])
        self.cbUseWin.setChecked(self.setting['useWin'])
        if self.setting['useDefDir']:
            self.leTargetDir.setEnabled(False)
            self.btnTargetDir.setEnabled(False)
        else:
            self.leTargetDir.setEnabled(True)
            self.btnTargetDir.setEnabled(True)

if __name__ == "__main__":
    import sys
    from PyQt5.QtWidgets import QApplication
    app = QApplication(sys.argv)
    dlg = DPy2Exe()
    dlg.show()
    sys.exit(app.exec_())
